package com.ph.shopping.facade.order.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.alibaba.dubbo.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ph.shopping.common.core.base.BaseService;
import com.ph.shopping.common.core.customenum.ResultEnum;
import com.ph.shopping.common.util.com.order.CreateOrderUtil;
import com.ph.shopping.common.util.com.order.OrderBizCode;
import com.ph.shopping.common.util.page.PageBean;
import com.ph.shopping.common.util.result.Result;
import com.ph.shopping.common.util.transform.MoneyTransUtil;
import com.ph.shopping.facade.mapper.AgentOrderMapper;
import com.ph.shopping.facade.mapper.AgentOrderProductsMapper;
import com.ph.shopping.facade.mapper.MerchantOrderMapper;
import com.ph.shopping.facade.mapper.PhMerchantOrderMapper;
import com.ph.shopping.facade.mapper.PhMerchantOrderProductsMapper;
import com.ph.shopping.facade.mapper.PhProductForOderUseVoMapper;
import com.ph.shopping.facade.mapper.PhTradersPasswordForOrderMapper;
import com.ph.shopping.facade.order.service.check.ParamsCheck;
import com.ph.shopping.facade.product.service.IProductService;
import com.ph.shopping.facade.product.vo.PhProductVo;

import cm.ph.shopping.facade.order.dto.ProductDTO;
import cm.ph.shopping.facade.order.dto.ProductOrderDTO;
import cm.ph.shopping.facade.order.entity.PhMerchantOrder;
import cm.ph.shopping.facade.order.entity.PhMerchantOrderProducts;
import cm.ph.shopping.facade.order.request.OrderRequest;
import cm.ph.shopping.facade.order.service.IMerchantOrderService;
import cm.ph.shopping.facade.order.vo.PhMerchantOrderListVo;
import cm.ph.shopping.facade.order.vo.PhProductForOderUseVo;
import cm.ph.shopping.facade.order.vo.PhTradersPasswordForOrderVo;
import cm.ph.shopping.facade.order.vo.QueryOrderDetailVo;

@Component
@Service(version="1.0.0")
@org.springframework.stereotype.Service
public class PhMerchantOrderServiceImpl extends BaseService implements IMerchantOrderService {
    private static Logger logger = LoggerFactory.getLogger(PhMerchantOrderServiceImpl.class);

	@Autowired
	private PhMerchantOrderMapper phMerchantOrderMapper;

    private MoneyTransUtil moneyTransUtil;

    @Autowired
    MerchantOrderMapper merchantOrderMapper;

    @Autowired
    PhMerchantOrderProductsMapper phMerchantOrderProductsMapper;

    @Autowired
    PhProductForOderUseVoMapper phProductForOderUseVoMapper;

    @Autowired
    AgentOrderMapper agentOrderMapper;

    @Autowired
    AgentOrderProductsMapper agentOrderProductsMapper;

    @Reference(version = "1.0.0")
    IProductService productService;
    
    @Autowired
    private   PhTradersPasswordForOrderMapper   phTradersPasswordForOrderMapper;

    @Override
	public Result getMerchantOrderList(PageBean pageBean, PhMerchantOrderListVo phMerchantOrderListVo)  throws Exception{
		PageHelper.startPage(pageBean.getPageNum(), pageBean.getPageSize(), "createTime desc");
		List<PhMerchantOrderListVo> list = (Page<PhMerchantOrderListVo>)phMerchantOrderMapper.getMerchantOrderList(phMerchantOrderListVo);
		PageInfo<PhMerchantOrderListVo> pageInfo = new PageInfo<>(list);
		return new Result(ResultEnum.SUCCESS.getCode(),"" , pageInfo.getList(), pageInfo.getTotal());
	}

	@Override
	public QueryOrderDetailVo getOrderDetail(QueryOrderDetailVo queryOrderDetailVo) {
        QueryOrderDetailVo orderDetailVo = phMerchantOrderMapper.getOrderDetail(queryOrderDetailVo);
        orderDetailVo.setOrderProductsList(phMerchantOrderMapper.getOrderProductList(queryOrderDetailVo));
        return orderDetailVo;
    }

	@Override
	public Result updateLogistics(PhMerchantOrder phMerchantOrder) {
        BigDecimal money = moneyTransUtil.transMulti(phMerchantOrder.getMoney());
        BigDecimal freight = moneyTransUtil.transMulti(phMerchantOrder.getFreight());
        BigDecimal totalCost = money.add(freight);
        phMerchantOrder.setMoney(money);
        phMerchantOrder.setFreight(freight);
        phMerchantOrder.setTotalCost(totalCost);
        phMerchantOrderMapper.updateByPrimaryKeySelective(phMerchantOrder);
		return getResult(ResultEnum.SUCCESS);
	}

    @Override
    public Result updateLogisticsInfo(PhMerchantOrder phMerchantOrder) {
        phMerchantOrderMapper.updateByPrimaryKeySelective(phMerchantOrder);
        return getResult(ResultEnum.SUCCESS);
    }
    
    @Override
    public Result updateForShipping(PhMerchantOrder phMerchantOrder) {
        phMerchantOrderMapper.updateByPrimaryKeySelective(phMerchantOrder);
        return getResult(ResultEnum.SUCCESS);
    }


    /**
     * 新增下货订单
     * @param merchantOrderRequest
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result addOrders(OrderRequest merchantOrderRequest) {
        long beginTime = System.currentTimeMillis();
        logger.info("新增下货订单入参: merchantOrderRequest={},开始时间={}", JSON.toJSONString(merchantOrderRequest), beginTime);
        Result result = new Result();
        result.setCode("80100");
        result.setMessage("参数不能为空");
        try {
            //存在并发问题（商品库存部分）
            //参数校验,返回空串表示参数校验通过
            if (ParamsCheck.checkAddOrders(merchantOrderRequest)) {
                //数据准确性和商品数量
                List<ProductOrderDTO> productOrderDTOList  = merchantOrderRequest.getProductOrderDTOList();
                checkStock(productOrderDTOList);
                //订单数据新增
                addOrder(productOrderDTOList,merchantOrderRequest.getOrderType());
                result = getResult(ResultEnum.SUCCESS);
            }
        } catch (Exception ex) {
            logger.error("新增下货订单异常,ex={}", ex);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            String message =  ex.getMessage();
            if (StringUtils.isNotEmpty(message) && message.contains("订单")) {
                result.setMessage(message);
            } else {
                result.setMessage("新增订单失败");
            }
            result.setCode("80001");
        }
        logger.info("新增下货订单返回: result={},耗时={}", JSON.toJSONString(result), System.currentTimeMillis()-beginTime);
        return result;
    }

    /**
     * 检查库存
     * @param productOrderDTOList
     */
    public boolean checkStock(List<ProductOrderDTO> productOrderDTOList) {
        for (ProductOrderDTO productOrderDTO : productOrderDTOList) {
            for (ProductDTO productDTO : productOrderDTO.getProductDTOList()) {
                if (!reduceStock(productDTO)) {
                    String message =  "新增订单失败，编号为：" + productDTO.getProductId() + "的商品目前库存不足，请重新选择";
                    throw new RuntimeException(message);
                }
            }
        }
        return true;
    }

    /**
     * 库存扣除（减去商品数量）
     * @param productDTO
     * @return 返回true表示校验成功
     */
    private boolean reduceStock(ProductDTO productDTO) {
        //如果商品数量不足，则订单不能生成，返回提示信息
        boolean flag = false;
        PhProductForOderUseVo phProductVo = new PhProductForOderUseVo();
        phProductVo.setId(productDTO.getProductId());
        phProductVo.setProductCount(productDTO.getNum());
        int num = phProductForOderUseVoMapper.reduceStock(phProductVo);
        if (num >= 1) {
            flag = true;
        }
        return flag;
    }


    /**
     * 新增订单实现方式
     * @param productOrderDTOList
     * @return
     */
    private boolean addOrder(List<ProductOrderDTO> productOrderDTOList,Integer orderType) {
        PhMerchantOrder phMerchantOrder;
        String desc = "",name = "";
        PhMerchantOrderProducts phMerchantOrderProducts;
        BigDecimal orderTotalCost,productTotalCost;
        BigDecimal price;
        Integer num = 0;
        PhProductVo phProductVo;
        List<PhMerchantOrderProducts> phMerchantOrderProductsList;
        for (ProductOrderDTO productOrderDTO : productOrderDTOList) {
            orderTotalCost = new BigDecimal(0);
            //商品信息
            List<ProductDTO> productDTOList = productOrderDTO.getProductDTOList();
            //一个供应商生成一个订单
            if (CollectionUtils.isNotEmpty(productDTOList)) {
                phMerchantOrderProductsList = new ArrayList<>();
                for (ProductDTO productDTO : productDTOList) {
                    productTotalCost = new BigDecimal(0);
                    phMerchantOrderProducts = new PhMerchantOrderProducts();
                    BeanUtils.copyProperties(productDTO,phMerchantOrderProducts);
                    //查询商品单价
                    phProductVo = getProductPrice(productDTO.getProductId());
                    price = new BigDecimal(0);
                    //如果单价为空，则用页面传入的
                    if (orderType.intValue() == 1) {
                        price = phProductVo.getPurchasePrice() == null ? productDTO.getPurchasePrice() : phProductVo.getPurchasePrice();
                    } else if (orderType.intValue() == 2) {
                        price = phProductVo.getSettlementPrice() == null ? productDTO.getPurchasePrice() : phProductVo.getSettlementPrice();
                    }
                    //该商品的总价
                    productTotalCost = price.multiply(new BigDecimal(productDTO.getNum()));
                    phMerchantOrderProducts.setTotalMoney(MoneyTransUtil.transMulti(productTotalCost));
                    phMerchantOrderProducts.setRetailPrice(MoneyTransUtil.transMulti(phProductVo.getRetailPrice()));
                    phMerchantOrderProducts.setSettlementPrice(MoneyTransUtil.transMulti(phProductVo.getSettlementPrice()));
                    phMerchantOrderProducts.setPurchasePrice(MoneyTransUtil.transMulti(phMerchantOrderProducts.getPurchasePrice()));
                    //订单的总价
                    orderTotalCost = orderTotalCost.add(productTotalCost);
                    //该供应商对应的商品集合
                    phMerchantOrderProductsList.add(phMerchantOrderProducts);
                    //商品总数量
                    num += productDTO.getNum();
                }
                //订单对象数据封装
                phMerchantOrder = new PhMerchantOrder();
                BeanUtils.copyProperties(productOrderDTO,phMerchantOrder);
                name = productDTOList.get(0).getProductName();
                if (productDTOList.size() > 1) {
                    desc = name + "等" + num + "个商品";
                } else {
                    desc = name + num + "个商品";
                }
                phMerchantOrder.setDescription(desc);
                phMerchantOrder.setCreateTime(new Date());
                phMerchantOrder.setStatus(0);
                orderTotalCost = MoneyTransUtil.transMulti(orderTotalCost);
                phMerchantOrder.setMoney(orderTotalCost);
                phMerchantOrder.setTotalCost(orderTotalCost);
                phMerchantOrder.setDescription(desc);
                phMerchantOrder.setUpdateTime(new Date());
                if (orderType.intValue() == 1) {
                    //获取订单编号
                    phMerchantOrder.setOrderNo(CreateOrderUtil.createOrderCode(OrderBizCode.MERCHANT_GOODS));
                    //新增商户订单
                    merchantOrderMapper.insertMerchantOrder(phMerchantOrder);
                    if (phMerchantOrder.getId() == null) throw new RuntimeException("新增订单失败，执行后未生成订单id");
                    //新增商品
                    phMerchantOrderProductsMapper.insertMerchantOrderProducts(phMerchantOrderProductsList,phMerchantOrder.getId());
                } else if(orderType.intValue() == 2) {
                    //获取订单编号
                    phMerchantOrder.setOrderNo(CreateOrderUtil.createOrderCode(OrderBizCode.AGENT_GOODS));
                    //新增代理商订单
                    agentOrderMapper.insertAgentOrder(phMerchantOrder);
                    if (phMerchantOrder.getId() == null) throw new RuntimeException("新增订单失败，执行后未生成订单id");
                    //新增商品
                    agentOrderProductsMapper.insertAgentOrderProducts(phMerchantOrderProductsList,phMerchantOrder.getId());
                }
            }
        }
        return true;
    }

    /**
     * 查询商品进货价
     * @param id
     * @return
     */
    private PhProductVo getProductPrice(Long id) {
        PhProductVo phProductVo = new PhProductVo();
        phProductVo.setId(id);
        PhProductVo phProductResult = null;
        try {
            logger.info("查询商品信息接口入参，phProductVo={}", JSON.toJSONString(phProductVo));
            phProductResult = productService.getPhProductVo(phProductVo);
            logger.info("查询商品信息接口返回值，phProductVo={}",JSON.toJSONString(phProductResult));
        } catch (Exception e) {
            logger.error("查询商品信息接口异常，ex={}", e);
        }
        return phProductResult;
    }
    	/**
    	 * 查询订单单条数据
    	 * @param merchantOrders
    	 * @return
    	 *
    	 */
    	@Override
    	public  	PhMerchantOrder   findMerchantOrderByTarget(PhMerchantOrder merchantOrders){
    				return   this.phMerchantOrderMapper.selectOne(merchantOrders);
    	}
    	
    	/**
    	 * 验证支付密码方法
    	 * @param merchantOrders
    	 * @return
    	 * @author yyg
    	 */
    	@Override
    	public   PhTradersPasswordForOrderVo	checkTradersPassword(PhTradersPasswordForOrderVo passwordForOrderVo){
    				return   this.phTradersPasswordForOrderMapper.checkTradersPassword(passwordForOrderVo);
    	}

    	
    	 @Override
    	    public int updateForOrderStatus(PhMerchantOrder phMerchantOrder) {
    	     int msg=   phMerchantOrderMapper.updateByPrimaryKeySelective(phMerchantOrder);
    	        return msg;
    	    }
}
